using MediatR;
using S.O.Api.Read.Application.Command.Medical;
using S.O.Domain.Dto.Output;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using Microsoft.Extensions.Logging;
using AutoMapper;

namespace S.O.Api.Read.Application.Handler.Medical
{
    /// <summary>
    /// 获取患者药品信息处理器
    /// 用于门诊收费页面显示患者的药品费用明细
    /// </summary>
    public class GetPatientMedicinesHandler : IRequestHandler<GetPatientMedicinesCommand, APIResult<List<PatientMedicineDto>>>
    {
        /// <summary>
        /// 处方信息仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionModel> _prescriptionRepository;
        
        /// <summary>
        /// 处方药品明细仓储
        /// </summary>
        private readonly IBaseRepository<PrescriptionMedicineModel> _prescriptionMedicineRepository;
        
        /// <summary>
        /// 挂号记录仓储
        /// </summary>
        private readonly IBaseRepository<RegistrationModel> _registrationRepository;
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<GetPatientMedicinesHandler> _logger;
        
        /// <summary>
        /// 对象映射器
        /// </summary>
        private readonly IMapper _mapper;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="prescriptionRepository">处方信息仓储</param>
        /// <param name="prescriptionMedicineRepository">处方药品明细仓储</param>
        /// <param name="registrationRepository">挂号记录仓储</param>
        /// <param name="mapper">对象映射器</param>
        /// <param name="logger">日志记录器</param>
        public GetPatientMedicinesHandler(
            IBaseRepository<PrescriptionModel> prescriptionRepository,
            IBaseRepository<PrescriptionMedicineModel> prescriptionMedicineRepository,
            IBaseRepository<RegistrationModel> registrationRepository,
            IMapper mapper,
            ILogger<GetPatientMedicinesHandler> logger)
        {
            _prescriptionRepository = prescriptionRepository;
            _prescriptionMedicineRepository = prescriptionMedicineRepository;
            _registrationRepository = registrationRepository;
            _mapper = mapper;
            _logger = logger;
        }

        /// <summary>
        /// 处理获取患者药品信息请求
        /// </summary>
        /// <param name="request">获取患者药品信息命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>患者药品信息列表</returns>
        public async Task<APIResult<List<PatientMedicineDto>>> Handle(GetPatientMedicinesCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取患者药品信息，患者ID：{PatientId}，挂单号：{RegistrationNo}", request.PatientId, request.RegistrationNo);
                
                // 获取所有未删除的数据
                var prescriptions = _prescriptionRepository.GetALL().Where(x => x.IsDeleted == false);
                var medicines = _prescriptionMedicineRepository.GetALL().Where(x => x.IsDeleted == false);
                var registrations = _registrationRepository.GetALL().Where(x => x.IsDeleted == false);
                
                // 构建基础查询：联结处方信息、处方药品明细和挂号记录
                // 由于PrescriptionModel没有RegistrationId字段，通过PatientId关联
                var query = from prescription in prescriptions
                           join medicine in medicines on prescription.Id equals medicine.PrescriptionId
                           join registration in registrations on prescription.PatientId equals registration.PatientId
                           where registration.PatientId == request.PatientId &&
                                 prescription.IsEnable == true &&
                                 medicine.IsEnable == true
                           select new { prescription, medicine, registration };
                
                // 如果提供了挂单号，则根据患者ID过滤处方（处方模型中没有RegistrationId字段）
                // 这里暂时注释掉挂单号过滤，因为PrescriptionModel没有RegistrationId字段
                // if (!string.IsNullOrWhiteSpace(request.RegistrationNo))
                // {
                //     // 需要通过其他方式关联挂单号和处方
                // }
                
                // 如果只获取未付费药品
                if (request.OnlyUnpaid)
                {
                    query = query.Where(x => x.medicine.IsPaid == false);
                }
                
                // 按开药时间倒序排序并执行查询
                var results = query
                    .OrderByDescending(x => x.prescription.CreateTime)
                    .Select(x => new PatientMedicineDto
                    {
                        MedicineId = x.medicine.Id.ToString(),
                        MedicineName = x.medicine.MedicineName,
                        Specification = x.medicine.Specification,
                        Quantity = x.medicine.Quantity,
                        UnitPrice = x.medicine.UnitPrice,
                        Amount = x.medicine.Amount,
                        PrescriptionId = x.prescription.Id,
                        IsPaid = x.medicine.IsPaid,
                        PrescriptionDate = x.prescription.CreateTime
                    })
                    .ToList();
                
                _logger.LogInformation("成功获取患者药品信息，共 {Count} 条记录", results.Count);
                
                return new APIResult<List<PatientMedicineDto>>
                {
                    Code = APIEnums.Success,
                    Msg = "获取成功",
                    Data = results
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取患者药品信息时发生异常，患者ID：{PatientId}", request.PatientId);
                return new APIResult<List<PatientMedicineDto>>
                {
                    Code = APIEnums.Error,
                    Msg = "获取患者药品信息失败",
                    Data = new List<PatientMedicineDto>()
                };
            }
        }
    }
}